home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q1082.dms / q1082.adf / src.lzh / Fig / intui.c < prev    next >
C/C++ Source or Header  |  1991-07-18  |  21KB  |  1,157 lines

  1. #define ZOOMWIDTH    40
  2. #define ZOOMHEIGHT    40
  3.  
  4. #include "fig.h"
  5. #include "paintop.h"
  6. #include "resources.h"
  7. #include "const.h"
  8.  
  9. extern int    figure_modified;
  10. extern char    current_file[];
  11. extern int    magnet_mode;
  12.  
  13. extern void (*canvas_locmove_proc)();
  14. extern void (*canvas_leftbut_proc)();
  15. extern void (*canvas_middlebut_proc)();
  16. extern void (*canvas_rightbut_proc)();
  17. extern void (*canvas_kbd_proc)();
  18.  
  19. extern void null_proc();
  20. extern char_handler();
  21.  
  22. struct Window    *figwin;
  23. struct RastPort    *RastPort;
  24.  
  25. typedef struct switch_struct
  26. {
  27.     int         on;
  28.     int         group;
  29.     int         x;    /* Row 0 / 1 */
  30.     int         y;    /* Column 0 -> ? */
  31.     struct iconpic    *icon;
  32.     int         value;
  33.     int        (*on_func)();
  34.     int        (*off_func)();
  35.     int         type;
  36. } F_switch;
  37.  
  38. extern F_switch switches[];
  39.  
  40. struct TextAttr StandardFont =
  41. {
  42.     (UBYTE *)"topaz.font",
  43.     8,
  44.     FS_NORMAL,
  45.     FPF_ROMFONT
  46. };
  47.  
  48. struct NewScreen NewScreen =
  49. {
  50.     0,0,640,STDSCREENHEIGHT,1,
  51.     0,1,
  52.     HIRES|LACE,
  53.     CUSTOMSCREEN,
  54.     (struct TextAttr *)&StandardFont,
  55.     (STRPTR)"FIG: Facility For Interactive Generation Of Figures",
  56.     (struct Gadget *)NULL,
  57.     (struct BitMap *)NULL
  58. };
  59.  
  60. struct NewWindow NewWindow =
  61. {
  62.     0,11,
  63.     640,501,
  64.     0,1,
  65.     RAWKEY | MOUSEBUTTONS | MOUSEMOVE | GADGETDOWN | MENUPICK | INTUITICKS,
  66.     ACTIVATE | BORDERLESS | BACKDROP | REPORTMOUSE,
  67.     (struct Gadget *)NULL,
  68.     (struct Image *)NULL,
  69.     (STRPTR)NULL,
  70.     (struct Screen *)NULL,
  71.     (struct BitMap *)NULL,
  72.     ~0,~0,
  73.     ~0,~0,
  74.     CUSTOMSCREEN
  75. };
  76.  
  77. struct SmallMenu
  78. {
  79.     UBYTE    *Title;
  80.     UBYTE     Command;
  81. };
  82.  
  83. STATIC struct SmallMenu Menus[] =
  84. {
  85.     {    "Undo",            'U'    },
  86.     {    "Redisplay",        'R'    },
  87.     {    "Remove All",        'E'    },
  88.     {    "Open File...",        'O'    },
  89.     {    "Save",            0    },
  90.     {    "Insert File...",    'I'    },
  91.     {    "Save File As...",    'S'    },
  92.     {    "Status",        '?'    },
  93.     {    "Save & Quit",        0    },
  94.     {    "Quit",            'Q'    },
  95.     {    "Save As IFF-ILBM",    0    },
  96.     {    "Display Mode...",    'M'    },
  97.     {    "Zoom Window",        'Z'    },
  98. };
  99.  
  100. struct ReqLib        *ReqBase;
  101. struct IntuitionBase    *IntuitionBase;
  102. struct GfxBase        *GfxBase;
  103. struct Library        *GadToolsBase;
  104. struct Library        *LayersBase;
  105.  
  106. extern struct ExecBase    *SysBase;
  107.  
  108. struct IOStdReq        *ConsoleRequest;
  109. struct Library        *ConsoleDevice;
  110.  
  111. struct MsgPort        *InputPort;
  112. struct IOStdReq        *InputRequest;
  113.  
  114. struct Screen        *Screen;
  115. struct Window        *Window,*AnotherWindow;
  116. extern struct Window    *ZoomWindow;
  117.  
  118. struct Process        *ThisProcess;
  119. APTR             OldPtr;
  120.  
  121. UWORD            *Sprite;
  122. struct Menu        *Menu;
  123.  
  124. struct TextFont        *fig_font;
  125.  
  126. struct ReqFileRequester     LoadFileRequest,SaveFileRequest;
  127. UBYTE             FileName1[FCHARS],FileName2[FCHARS];
  128. UBYTE             DirectoryName1[DSIZE],DirectoryName2[DSIZE];
  129. UBYTE             TempName[FCHARS+DSIZE];
  130.  
  131. STATIC BYTE         MoveCount = 0;
  132.  
  133. extern APTR         _ONGURU;
  134.  
  135. extern ULONG         GetDisplayMode();
  136.  
  137. VOID
  138. FlushMsg()
  139. {
  140.     struct IntuiMessage *Massage;
  141.  
  142.     while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  143.         ReplyMsg(Massage);
  144. }
  145.  
  146. VOID
  147. CloseWindowSafely(struct Window *Window)
  148. {
  149.     struct IntuiMessage    *IntuiMessage;
  150.     struct Node        *Successor;
  151.  
  152.     Forbid();
  153.  
  154.     IntuiMessage = (struct IntuiMessage *)Window -> UserPort -> mp_MsgList . lh_Head;
  155.  
  156.     while(Successor = IntuiMessage -> ExecMessage . mn_Node . ln_Succ)
  157.     {
  158.         if(IntuiMessage -> IDCMPWindow == Window)
  159.         {
  160.             Remove(IntuiMessage);
  161.             ReplyMsg((struct Message *)IntuiMessage);
  162.         }
  163.  
  164.         IntuiMessage = (struct IntuiMessage *)Successor;
  165.     }
  166.  
  167.     Window -> UserPort = NULL;
  168.  
  169.     ModifyIDCMP(Window,NULL);
  170.     Permit();
  171.  
  172.     CloseWindow(Window);
  173. }
  174.  
  175. VOID
  176. CloseAll()
  177. {
  178.     ThisProcess -> pr_WindowPtr = OldPtr;
  179.  
  180.     if(ConsoleRequest)
  181.     {
  182.         if(ConsoleRequest -> io_Device)
  183.             CloseDevice(ConsoleRequest);
  184.  
  185.         FreeMem(ConsoleRequest,sizeof(struct IOStdReq));
  186.  
  187.         ConsoleRequest = NULL;
  188.     }
  189.  
  190.     if(InputRequest)
  191.     {
  192.         if(InputRequest -> io_Device)
  193.             CloseDevice(InputRequest);
  194.  
  195.         DeleteStdIO(InputRequest);
  196.  
  197.         InputRequest = NULL;
  198.     }
  199.  
  200.     if(InputPort)
  201.     {
  202.         DeletePort(InputPort);
  203.  
  204.         InputPort = NULL;
  205.     }
  206.  
  207.     if(Screen)
  208.         ScreenToBack(Screen);
  209.  
  210.     CloseZoomWindow();
  211.  
  212.     if(AnotherWindow)
  213.     {
  214.         CloseWindowSafely(AnotherWindow);
  215.  
  216.         AnotherWindow = NULL;
  217.     }
  218.  
  219.     if(Window)
  220.     {
  221.         CloseWindow(Window);
  222.  
  223.         Window = NULL;
  224.     }
  225.  
  226.     if(Screen)
  227.     {
  228.         CloseScreen(Screen);
  229.  
  230.         Screen = NULL;
  231.     }
  232.  
  233.     if(Sprite)
  234.     {
  235.         FreeMem(Sprite,(17 + 2) * 2 * sizeof(UWORD));
  236.  
  237.         Sprite = NULL;
  238.     }
  239.  
  240.     if(Menu)
  241.     {
  242.         ClearMenu(Menu);
  243.  
  244.         Menu = NULL;
  245.     }
  246.  
  247.     if(fig_font)
  248.     {
  249.         CloseFont(fig_font);
  250.  
  251.         fig_font = NULL;
  252.     }
  253.  
  254.     ClearGadgets();
  255.  
  256.     if(ReqBase)
  257.     {
  258.         PurgeFiles(&LoadFileRequest);
  259.         PurgeFiles(&SaveFileRequest);
  260.  
  261.         CloseLibrary(ReqBase);
  262.  
  263.         ReqBase = NULL;
  264.     }
  265.  
  266.     if(LayersBase)
  267.     {
  268.         CloseLibrary(LayersBase);
  269.  
  270.         LayersBase = NULL;
  271.     }
  272.  
  273.     if(GadToolsBase)
  274.     {
  275.         CloseLibrary(GadToolsBase);
  276.  
  277.         GadToolsBase = NULL;
  278.     }
  279. }
  280.  
  281. VOID
  282. GuruCleanup()
  283. {
  284.     memcleanup();
  285.     mem_free();
  286.     CloseAll();
  287. }
  288.  
  289. BYTE
  290. OpenAll(struct Gadget *FirstGadget)
  291. {
  292.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  293.  
  294.     OldPtr = ThisProcess -> pr_WindowPtr;
  295.  
  296.     _ONGURU = GuruCleanup;
  297.  
  298.     if(!(InputPort = (struct MsgPort *)CreatePort(NULL,0)))
  299.         return(FALSE);
  300.  
  301.     if(!(InputRequest = (struct IOStdReq *)CreateStdIO(InputPort)))
  302.         return(FALSE);
  303.  
  304.     if(OpenDevice("input.device",0,InputRequest,0))
  305.         return(FALSE);
  306.  
  307.     if(!(ConsoleRequest = (struct IOStdReq *)AllocMem(sizeof(struct IOStdReq),MEMF_PUBLIC|MEMF_CLEAR)))
  308.         return(FALSE);
  309.  
  310.     if(OpenDevice("console.device",CONU_LIBRARY,ConsoleRequest,0))
  311.         return(FALSE);
  312.  
  313.     ConsoleDevice = &ConsoleRequest -> io_Device -> dd_Library;
  314.  
  315.     if(!(ReqBase = (struct ReqLib *)OpenLibrary("req.library",0)))
  316.         return(FALSE);
  317.  
  318.     if(!(LayersBase = OpenLibrary("layers.library",0)))
  319.         return(FALSE);
  320.  
  321.     IntuitionBase    = (struct IntuitionBase *)ReqBase -> IntuiLib;
  322.     GfxBase        = (struct GfxBase *)ReqBase -> GfxLib;
  323.  
  324.     if(!(Sprite = (UWORD *)AllocMem((17 + 2) * 2 * sizeof(UWORD),MEMF_CHIP|MEMF_CLEAR)))
  325.         return(FALSE);
  326.  
  327.     if(!(fig_font = (struct TextFont *)OpenFont(&StandardFont)))
  328.         return(FALSE);
  329.  
  330.     if(IntuitionBase -> LibNode . lib_Version >= 36)
  331.     {
  332.         struct Rectangle    DisplayClip;
  333.         ULONG            DisplayID;
  334.         LONG            Height;
  335.  
  336.         DisplayID = GetDisplayMode();
  337.  
  338.         if(!(GadToolsBase = OpenLibrary("gadtools.library",36)))
  339.             return(FALSE);
  340.  
  341.         if(!QueryOverscan(DisplayID,&DisplayClip,OSCAN_TEXT))
  342.             return(FALSE);
  343.  
  344.         if((Height = (DisplayClip . MaxY - DisplayClip . MinY) + 1) < 480)
  345.             Height = 480;
  346.  
  347.         Screen = (struct Screen *)OpenScreenTags(NULL,
  348.             SA_Height,    Height,
  349.             SA_Overscan,    OSCAN_TEXT,
  350.             SA_Depth,    1,
  351.             SA_Title,    NewScreen . DefaultTitle,
  352.             SA_Font,    &StandardFont,
  353.             SA_DisplayID,    DisplayID,
  354.             SA_AutoScroll,    TRUE,
  355.         TAG_DONE);
  356.  
  357.         NewWindow . TopEdge = 12;
  358.     }
  359.     else
  360.         Screen = (struct Screen *)OpenScreen(&NewScreen);
  361.  
  362.     if(!Screen)
  363.         return(FALSE);
  364.  
  365.     NewWindow . Height    = Screen -> Height - NewWindow . TopEdge;
  366.     NewWindow . Width    = 96;
  367.  
  368.     NewWindow . FirstGadget    = FirstGadget;
  369.     NewWindow . Screen    = Screen;
  370.  
  371.     if(!(Window = (struct Window *)OpenWindow(&NewWindow)))
  372.         return(FALSE);
  373.  
  374.     NewWindow . LeftEdge    = 96;
  375.  
  376.     NewWindow . Flags    |= RMBTRAP;
  377.  
  378.     NewWindow . IDCMPFlags    = NULL;
  379.     NewWindow . FirstGadget    = NULL;
  380.  
  381.     NewWindow . Width    = Screen -> Width - 96;
  382.  
  383.     if(!(AnotherWindow = (struct Window *)OpenWindow(&NewWindow)))
  384.         return(FALSE);
  385.  
  386.     AnotherWindow -> UserPort = Window -> UserPort;
  387.  
  388.     ModifyIDCMP(AnotherWindow,RAWKEY | MOUSEBUTTONS | MOUSEMOVE | GADGETDOWN | MENUPICK | INTUITICKS);
  389.  
  390.     ThisProcess -> pr_WindowPtr = (APTR)Window;
  391.  
  392.     return(TRUE);
  393. }
  394.  
  395. UBYTE *
  396. DoFileRequest(UBYTE *Title,UBYTE *Buffer,BYTE DoSave)
  397. {
  398.     struct ReqFileRequester *TempFileRequest;
  399.  
  400.     if(DoSave)
  401.         TempFileRequest = &SaveFileRequest;
  402.     else
  403.         TempFileRequest = &LoadFileRequest;
  404.  
  405.     TempFileRequest -> PathName        = Buffer;
  406.     TempFileRequest -> Title        = Title;
  407.     TempFileRequest -> dirnamescolor    = 1;
  408.     TempFileRequest -> devicenamescolor    = 1;
  409.     TempFileRequest -> Window        = Window;
  410.  
  411.     TempFileRequest -> numlines        = Window -> Height >> 3;
  412.  
  413.     if(DoSave)
  414.     {
  415.         TempFileRequest -> Dir        = DirectoryName1;
  416.         TempFileRequest -> File        = FileName1;
  417.         TempFileRequest -> Flags    = FRQCACHINGM | FRQINFOGADGETM | FRQNOHALFCACHEM | FRQSAVINGM | FRQCACHEPURGEM;
  418.         TempFileRequest -> blockcolor    = 1;
  419.     }
  420.     else
  421.     {
  422.         TempFileRequest -> Dir        = DirectoryName2;
  423.         TempFileRequest -> File        = FileName2;
  424.         TempFileRequest -> Flags    = FRQCACHINGM | FRQINFOGADGETM | FRQNOHALFCACHEM | FRQLOADINGM;
  425.         TempFileRequest -> blockcolor    = 1;
  426.     }
  427.  
  428.     if(FileRequester(TempFileRequest))
  429.     {
  430.         Window -> Flags |= REPORTMOUSE;
  431.  
  432.         return(Buffer);
  433.     }
  434.     else
  435.     {
  436.         Window -> Flags |= REPORTMOUSE;
  437.  
  438.         return(NULL);
  439.     }
  440. }
  441.  
  442. VOID
  443. KeyConvert(struct IntuiMessage *Massage)
  444. {
  445.     STATIC struct InputEvent Event = { NULL, IECLASS_RAWKEY, 0, 0, 0 };
  446.  
  447.     if(Massage -> Class == RAWKEY)
  448.     {
  449.         if(!(Massage -> Code & IECODE_UP_PREFIX))
  450.         {
  451.             UBYTE Buffer[10];
  452.  
  453.             Buffer[0] = 0;
  454.  
  455.             Event . ie_Code            = Massage -> Code;
  456.             Event . ie_Qualifier        = Massage -> Qualifier;
  457.  
  458.             Event . ie_position . ie_addr    = *((APTR *)Massage -> IAddress);
  459.  
  460.             if(RawKeyConvert(&Event,Buffer,10,NULL) > 0)
  461.             {
  462.                 if(Buffer[0] != 155)
  463.                     Massage -> Code = Buffer[0];
  464.                 else
  465.                     Massage -> Code = 0;
  466.             }
  467.             else
  468.                 Massage -> Code = 0;
  469.         }
  470.         else
  471.             Massage -> Code = 0;
  472.     }
  473. }
  474.  
  475. VOID
  476. Zoom(SHORT X,SHORT Y)
  477. {
  478.     SHORT NewX,NewY;
  479.  
  480.     if(X < 0)
  481.         X = 0;
  482.  
  483.     if(Y < 0)
  484.         Y = 0;
  485.  
  486.     NewX = X;
  487.     NewY = Y;
  488.  
  489.     if(X - (ZOOMWIDTH >> 1) > 0)
  490.         NewX -= (ZOOMWIDTH >> 1);
  491.     else
  492.         NewX = 0;
  493.  
  494.     if(NewX + ZOOMWIDTH > AnotherWindow -> Width)
  495.         NewX = AnotherWindow -> Width - ZOOMWIDTH;
  496.  
  497.     if(Y - (ZOOMHEIGHT >> 1) > 0)
  498.         NewY -= (ZOOMHEIGHT >> 1);
  499.     else
  500.         NewY = 0;
  501.  
  502.     if(NewY + ZOOMHEIGHT > AnotherWindow -> Height)
  503.         NewY = AnotherWindow -> Height - ZOOMHEIGHT;
  504.  
  505.     ZoomToWindow(AnotherWindow -> RPort,NewX,NewY,X - NewX,Y - NewY);
  506. }
  507.  
  508. VOID
  509. KeyAction(UBYTE Key)
  510. {
  511.     switch(toupper(Key))
  512.     {
  513.         case 'U':    undo();
  514.                 break;
  515.  
  516.         case 'R':    redisplay_canvas();
  517.                 break;
  518.  
  519.         case 'E':    remove_all();
  520.                 put_msg("Immediate Undo will restore the figure.");
  521.                 redisplay_canvas();
  522.                 break;
  523.  
  524.         case 'O':    if (!no_object() && figure_modified)
  525.                 {
  526.                     if(!TwoGadRequest("Figures   have   been  modified, please\nconfirm that you wish to continue."))
  527.                     {
  528.                         FlushMsg();
  529.  
  530.                         break;
  531.                     }
  532.                 }
  533.  
  534.                 if(DoFileRequest("Open File...",TempName,FALSE))
  535.                     edit_file(TempName);
  536.  
  537.                 FlushMsg();
  538.  
  539.                 break;
  540.  
  541.         case 'I':    if(DoFileRequest("Insert File...",TempName,FALSE))
  542.                     read_file(TempName);
  543.  
  544.                 FlushMsg();
  545.  
  546.                 break;
  547.  
  548.         case 'S':    if (no_object())
  549.                 {
  550.                     put_msg("No figure to save. Abort save operation.");
  551.                     break;
  552.                 }
  553.  
  554.                 if(DoFileRequest("Save File As...",TempName,FALSE))
  555.                     save_file(TempName);
  556.  
  557.                 FlushMsg();
  558.  
  559.                 break;
  560.  
  561.         case '?':    status();
  562.                 break;
  563.  
  564.         case 'Q':    quit();
  565.  
  566.                 FlushMsg();
  567.  
  568.                 break;
  569.  
  570.         case 'M':    if(SysBase -> LibNode . lib_Version >= 36)
  571.                 {
  572.                     DisplayModePrefs();
  573.  
  574.                     FlushMsg();
  575.                 }
  576.  
  577.                 break;
  578.  
  579.         case 'Z':    if(SysBase -> LibNode . lib_Version >= 36)
  580.                 {
  581.                     if(!ZoomWindow)
  582.                     {
  583.                         if(OpenZoomWindow())
  584.                         {
  585.                             Zoom(AnotherWindow -> MouseX,AnotherWindow -> MouseY);
  586.  
  587.                             MoveCount = 0;
  588.                         }
  589.                     }
  590.                     else
  591.                         CloseZoomWindow();
  592.                 }
  593.  
  594.                 break;
  595.  
  596.         default:    break;
  597.     }
  598. }
  599.  
  600. VOID
  601. HandleInput()
  602. {
  603.     struct IntuiMessage    *Massage;
  604.     ULONG             Class,Code,Qualifier;
  605.     LONG             X = 0,Y = 0,T,ScreenY;
  606.     LONG             CentiX,CentiY;
  607.     BYTE             KeepGoing = TRUE;
  608.  
  609.     ULONG             SignalSet;
  610.  
  611.     struct MenuItem        *MenuItem;
  612.     SHORT             MenuNum;
  613.  
  614.     LONG             GadgetCounter;
  615.     LONG             LeftEdge;
  616.     UBYTE             PositionBuffer[13];
  617.     SHORT             LastHit = -1;
  618.  
  619.     if(IntuitionBase -> LibNode . lib_Version >= 36)
  620.         LeftEdge = Screen -> Width - (17 + 8 * 14);
  621.     else
  622.         LeftEdge = Screen -> Width - (48 + 8 * 14);
  623.  
  624.     while(KeepGoing)
  625.     {
  626.         SignalSet = (1 << Window -> UserPort -> mp_SigBit);
  627.  
  628.         if(ZoomWindow)
  629.             SignalSet |= (1 << ZoomWindow -> UserPort -> mp_SigBit);
  630.  
  631.         SignalSet = Wait(SignalSet);
  632.  
  633.         if(SignalSet & (1 << Window -> UserPort -> mp_SigBit))
  634.         {
  635.             while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  636.             {
  637.                 if((GadgetCounter = HandleGadget(Window,Massage)) >= 0)
  638.                 {
  639.                     if(GadgetCounter <= 27)
  640.                     {
  641.                         if(LastHit != -1)
  642.                         {
  643.                             if(LastHit != GadgetCounter)
  644.                                 (*canvas_middlebut_proc)(X,Y);
  645.                         }
  646.  
  647.                         LastHit = GadgetCounter;
  648.                     }
  649.  
  650.                     switch_action(&(switches[GadgetCounter]));
  651.                 }
  652.                 else
  653.                 {
  654.                     KeyConvert(Massage);
  655.  
  656.                     Class        = Massage -> Class;
  657.                     Code        = Massage -> Code;
  658.                     Qualifier    = Massage -> Qualifier;
  659.  
  660.                     if(Massage -> IDCMPWindow == AnotherWindow)
  661.                     {
  662.                         X = Massage -> MouseX;
  663.                         Y = Massage -> MouseY;
  664.                     }
  665.                     else
  666.                     {
  667.                         struct Layer *Layer;
  668.  
  669.                         if(Layer = WhichLayer(&Screen -> LayerInfo,Screen -> MouseX,Screen -> MouseY))
  670.                         {
  671.                             if(Layer -> Window == AnotherWindow)
  672.                             {
  673.                                 X = AnotherWindow -> MouseX;
  674.                                 Y = AnotherWindow -> MouseY;
  675.                             }
  676.                         }
  677.  
  678.                         if(Class == MOUSEBUTTONS)
  679.                             Class = NULL;
  680.                     }
  681.  
  682.                     ScreenY = Screen -> MouseY;
  683.  
  684.                     ReplyMsg(&Massage -> ExecMessage);
  685.  
  686.                     if(X < 0)
  687.                         X = 0;
  688.  
  689.                     if(Y < 0)
  690.                         Y = 0;
  691.  
  692.                     if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  693.                         MoveCount = 0;
  694.  
  695.                     if(!MoveCount++)
  696.                     {
  697.                         CentiX = X * 100 / PIX_PER_CM;
  698.                         CentiY = Y * 100 / PIX_PER_CM;
  699.  
  700.                         sprintf(PositionBuffer,"X %3d  %2d.%02d",X,CentiX / 100,CentiX % 100);
  701.  
  702.                         SetAPen(Window -> RPort,1);
  703.                         SetBPen(Window -> RPort,0);
  704.  
  705.                         Move(Window -> RPort,0,32 * 14 + 6 + 1);
  706.                         Text(Window -> RPort,PositionBuffer,12);
  707.  
  708.                         sprintf(PositionBuffer,"Y %3d  %2d.%02d",Y,CentiY / 100,CentiY % 100);
  709.  
  710.                         SetAPen(Window -> RPort,1);
  711.                         SetBPen(Window -> RPort,0);
  712.  
  713.                         Move(Window -> RPort,0,32 * 14 + 6 + 1 + 8);
  714.                         Text(Window -> RPort,PositionBuffer,12);
  715.                     }
  716.  
  717.                     if(MoveCount > 3)
  718.                         MoveCount = 0;
  719.  
  720.                     switch(Class)
  721.                     {
  722.                         case MOUSEMOVE:
  723.  
  724.                             if(ScreenY < 11)
  725.                                 AnotherWindow -> Flags &= ~RMBTRAP;
  726.                             else
  727.                             {
  728.                                 AnotherWindow -> Flags |= RMBTRAP;
  729.  
  730.                                 if(magnet_mode)
  731.                                 {
  732.                                     X = ((T = X % 5) < 3) ? X - T - 1 : X + 5 - T - 1;
  733.                                     Y = ((T = Y % 5) < 3) ? Y - T - 1 : Y + 5 - T - 1;
  734.  
  735. /*                                    win_setmouseposition(figwin, X, Y);*/
  736.                                 }
  737.  
  738.                                 (*canvas_locmove_proc)(X, Y);
  739.  
  740.                                 if(ZoomWindow)
  741.                                 {
  742.                                     if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  743.                                         MoveCount = 0;
  744.  
  745.                                     if(!MoveCount)
  746.                                         Zoom(X,Y);
  747.                                 }
  748.                             }
  749.  
  750.                             break;
  751.  
  752.                         case MOUSEBUTTONS:
  753.  
  754.                             if(magnet_mode)
  755.                             {
  756.                                 X = ((T = X % 5) < 3) ? X - T - 1 : X + 5 - T - 1;
  757.                                 Y = ((T = Y % 5) < 3) ? Y - T - 1 : Y + 5 - T - 1;
  758.  
  759. /*                                win_setmouseposition(figwin, X, Y);*/
  760.                             }
  761.  
  762.                             if(Code == SELECTDOWN)
  763.                                 (*canvas_leftbut_proc)(X,Y);
  764.  
  765.                             if(Code == MENUDOWN)
  766.                                 (*canvas_middlebut_proc)(X,Y);
  767.  
  768.                             break;
  769.  
  770.                         case INTUITICKS:
  771.  
  772.                             timerfunc();
  773.  
  774.                             break;
  775.  
  776.                         case RAWKEY:
  777.  
  778.                             if(Code)
  779.                             {
  780.                                 if(LastHit == 11)
  781.                                     (*canvas_kbd_proc)(Code);
  782.                                 else
  783.                                     KeyAction(Code);
  784.                             }
  785.  
  786.                             break;
  787.  
  788.  
  789.                         case MENUPICK:
  790.                             MenuNum = Code;
  791.  
  792.                             while(MenuNum != MENUNULL)
  793.                             {
  794.                                 switch(ITEMNUM(MenuNum))
  795.                                 {
  796.                                     case 4:        save_current_file();
  797.                                             FlushMsg();
  798.                                             break;
  799.  
  800.                                     case 8:        if(!figure_modified)
  801.                                                 quit();
  802.  
  803.                                             if(no_object())
  804.                                                 quit();
  805.  
  806.                                             if(current_file[0])
  807.                                             {
  808.                                                 if(!write_file(current_file,0))
  809.                                                     quit();
  810.                                             }
  811.                                             else
  812.                                             {
  813.                                                 blink_msg();
  814.  
  815.                                                 if(DoFileRequest("Save & Quit...",TempName,TRUE))
  816.                                                     save_and_exit(TempName);
  817.                                             }
  818.  
  819.                                             break;
  820.  
  821.                                     case 10:    if(no_object())
  822.                                             {
  823.                                                 put_msg("No figure to save.");
  824.                                                 break;
  825.                                             }
  826.  
  827.                                             if(DoFileRequest("Save as IFF-ILBM...",TempName,TRUE))
  828.                                                 write_bitmap(TempName);
  829.  
  830.                                             FlushMsg();
  831.  
  832.                                             break;
  833.  
  834.                                     default:    KeyAction(Menus[ITEMNUM(MenuNum)] . Command);
  835.                                             break;
  836.                                 }
  837.  
  838.                                 if(!(MenuItem = (struct MenuItem *)ItemAddress(Menu,MenuNum)))
  839.                                     break;
  840.  
  841.                                 MenuNum = MenuItem -> NextSelect;
  842.                             }
  843.  
  844.                             break;
  845.  
  846.                         default:
  847.                             break;
  848.                     }
  849.                 }
  850.             }
  851.         }
  852.  
  853.         if(ZoomWindow)
  854.         {
  855.             if(SignalSet & (1 << ZoomWindow -> UserPort -> mp_SigBit))
  856.             {
  857.                 while(Massage = (struct IntuiMessage *)GetMsg(ZoomWindow -> UserPort))
  858.                 {
  859.                     Class = Massage -> Class;
  860.  
  861.                     ReplyMsg(&Massage -> ExecMessage);
  862.  
  863.                     if(Class == NEWSIZE)
  864.                     {
  865.                         DeleteZoomBitMap();
  866.                         CreateZoomBitMap();
  867.  
  868.                         Zoom(AnotherWindow -> MouseX,AnotherWindow -> MouseY);
  869.  
  870.                         MoveCount = 0;
  871.                     }
  872.  
  873.                     if(Class == CLOSEWINDOW)
  874.                     {
  875.                         CloseZoomWindow();
  876.                         break;
  877.                     }
  878.                 }
  879.             }
  880.         }
  881.     }
  882. }
  883.  
  884. struct Window *
  885. openfigwin(UBYTE *Name)
  886. {
  887.     extern MENUITEM     pumenu_items[];
  888.     extern int     N_SWITCHES;
  889.  
  890.     extern int     amicolor0,amicolor1;
  891.  
  892.     extern int     NUMMENUITEMS;
  893.  
  894.     struct Gadget    *FirstGadget = NULL,*Gadget;
  895.     LONG         i;
  896.  
  897.     for(i = 0 ; i < N_SWITCHES ; i++)
  898.     {
  899.         if(Gadget = (struct Gadget *)AddMyGadget((i % 3) * 32,(i / 3) * 32,32,32,switches[i] . group,switches[i] . on,switches[i] . icon -> data))
  900.         {
  901.             if(!FirstGadget)
  902.                 FirstGadget = Gadget;
  903.         }
  904.         else
  905.         {
  906.             ClearGadgets();
  907.  
  908.             FirstGadget = NULL;
  909.  
  910.             break;
  911.         }
  912.     }
  913.  
  914.     if(FirstGadget)
  915.     {
  916.         if(Menu = (struct Menu *)CreateMenu("FIG"))
  917.         {
  918.             SHORT Max = 11;
  919.  
  920.             if(SysBase -> LibNode . lib_Version >= 36)
  921.                 Max = 13;
  922.  
  923.             for(i = 0 ; i < Max ; i++)
  924.             {
  925.                 if(!AddItem(Menu,Menus[i] . Title,Menus[i] . Command))
  926.                 {
  927.                     ClearMenu(Menu);
  928.  
  929.                     Menu = NULL;
  930.  
  931.                     break;
  932.                 }
  933.             }
  934.  
  935.             if(Menu)
  936.             {
  937.                 if(OpenAll(FirstGadget))
  938.                 {
  939.                     if(amicolor0 != -1)
  940.                         SetRGB4(&Screen -> ViewPort,0,(amicolor0 >> 8) & 0xF,(amicolor0 >> 4) & 0xF,(amicolor0     ) & 0xF);
  941.  
  942.                     if(amicolor1 != -1)
  943.                         SetRGB4(&Screen -> ViewPort,1,(amicolor1 >> 8) & 0xF,(amicolor1 >> 4) & 0xF,(amicolor1     ) & 0xF);
  944.  
  945.                     RastPort = AnotherWindow -> RPort;
  946.  
  947.                     SetAPen(RastPort,1);
  948.  
  949.                     init_grid();
  950.  
  951.                     canvas_leftbut_proc    = null_proc;
  952.                     canvas_middlebut_proc    = null_proc;
  953.                     canvas_rightbut_proc    = null_proc;
  954.                     canvas_kbd_proc        = null_proc;
  955.                     canvas_locmove_proc    = null_proc;
  956.  
  957.                     init_switch();
  958.  
  959.                     SetMenuStrip(Window,Menu);
  960.                     SetMenuStrip(AnotherWindow,Menu);
  961.  
  962.                     figwin = AnotherWindow;
  963.  
  964. /*                    win_setcursor(figwin,&arrow_cursor);*/
  965.  
  966.                     return(Window);
  967.                 }
  968.                 else
  969.                     CloseAll();
  970.             }
  971.         }
  972.     }
  973.  
  974.     return(NULL);
  975. }
  976.  
  977. BYTE temporary_cursor = FALSE;
  978.  
  979. win_setcursor(window,cursor)
  980. struct Window * window;
  981. struct cursor * cursor;
  982. {
  983.     extern struct cursor *cur_cursor;
  984.     STATIC struct cursor *static_cursor = &arrow_cursor;
  985.     SHORT i;
  986.  
  987. /*    if(!cursor -> picture)*/
  988. /*        cursor = &arrow_cursor;*/
  989.  
  990.     if(!temporary_cursor)
  991.     {
  992.         cur_cursor = static_cursor;
  993.  
  994.         static_cursor = cursor;
  995.     }
  996.  
  997.     if(cursor -> picture)
  998.     {
  999.         for(i = 0 ; i < cursor -> picture -> ylen ; i++)
  1000.             Sprite[2 + 2 * i] = cursor -> picture -> data[i];
  1001.  
  1002.         Sprite[2 + 2 * i] = Sprite[4 + 2 * i] = 0;
  1003.  
  1004.         SetPointer(figwin,Sprite,cursor -> picture -> ylen,cursor -> picture -> xlen,-cursor -> actx,-cursor -> acty);
  1005.     }
  1006.     else
  1007.     {
  1008.         memset(Sprite,0,(2 + 16) * 2 * sizeof(UWORD));
  1009.  
  1010.         SetPointer(figwin,Sprite,1,1,0,0);
  1011.     }
  1012. }
  1013.  
  1014. /* INV_PAINT,MERGE,PAINT,ERASE */
  1015.  
  1016. int mode[] = {COMPLEMENT,JAM1,JAM2,JAM1};
  1017.  
  1018. set_gmode(colour)
  1019. {
  1020.     if(colour == ERASE)
  1021.         SetAPen(RastPort,0);
  1022.  
  1023.     SetDrMd(RastPort,mode[colour - 1]);
  1024. }
  1025.  
  1026. reset_gmode()
  1027. {
  1028.     SetAPen(RastPort,1);
  1029.     SetDrMd(RastPort,JAM1);
  1030. }
  1031.  
  1032. pw_put(window,x,y,colour)
  1033. struct Window * window;
  1034. {
  1035.     SetAPen(RastPort,colour);
  1036.     WritePixel(RastPort,x,y);
  1037.     SetAPen(RastPort,1);
  1038. }
  1039.  
  1040. pw_vector(window,x,y,x1,y1,colour,unknown)
  1041. struct Window * window;
  1042. {
  1043.     set_gmode(colour);
  1044.  
  1045.     Move(RastPort,x,y);
  1046.     Draw(RastPort,x1,y1);
  1047.  
  1048.     reset_gmode();
  1049. }
  1050.  
  1051. pw_write(window,x,y,width,height,colour,mask,u1,u2)
  1052. struct Window * window;
  1053. struct iconpic * mask;
  1054. {
  1055.     if(window == figwin)
  1056.     {
  1057.         set_gmode(colour);
  1058.  
  1059.         BltPattern(RastPort,(APTR)mask -> data,x,y,x + width - 1,y + height - 1,(y + 15) / 16);
  1060.  
  1061.         reset_gmode();
  1062.     }
  1063. }
  1064.  
  1065. pw_text(window,x,y,colour,font,string)
  1066. struct Window * window;
  1067. struct TextFont * font;
  1068. unsigned char * string;
  1069. {
  1070.     set_gmode(colour);
  1071.  
  1072.     Move(RastPort,x,y);
  1073.     Text(RastPort,string,strlen(string));
  1074.  
  1075.     reset_gmode(colour);
  1076. }
  1077.  
  1078. struct rastmem
  1079. {
  1080.     int     x,y;
  1081.     char    *ptr;
  1082. } RastMem[20];
  1083.  
  1084. int rastptr = 0;
  1085.  
  1086. USHORT *
  1087. mem_create(x,y)
  1088. {
  1089.     int i;
  1090.     char *ptr = (char *)AllocRaster(x,y);
  1091.  
  1092.     if(!ptr)
  1093.     {
  1094.         fprintf(stderr,"No memory.\n");
  1095.         _abort();
  1096.     }
  1097.  
  1098.     RastMem[rastptr] . x    = x;
  1099.     RastMem[rastptr] . y    = y;
  1100.     RastMem[rastptr] . ptr    = ptr;
  1101.  
  1102.     rastptr++;
  1103.  
  1104.     if(rastptr == 20)
  1105.     {
  1106.         fprintf(stderr,"No memory.\n");
  1107.         _abort();
  1108.     }
  1109.  
  1110.     for(i = 0 ; i < RASSIZE(x,y) ; i++)
  1111.         ptr[i] = 0;
  1112.  
  1113.     return (USHORT *)ptr;
  1114. }
  1115.  
  1116. mem_free()
  1117. {
  1118.     int i;
  1119.  
  1120.     for(i = 0 ; i < rastptr ; i++)
  1121.         FreeRaster(RastMem[i] . ptr,RastMem[i] . x,RastMem[i] . y);
  1122. }
  1123.  
  1124. PR_SIZE
  1125. pf_textwidth(len,font,str)
  1126. int len;
  1127. struct TextFont * font;
  1128. char * str;
  1129. {
  1130.     PR_SIZE x;
  1131.  
  1132.     x . x = len * font -> tf_XSize;
  1133.     x . y = font -> tf_YSize;
  1134.  
  1135. /*    x . x = len * 8;*/
  1136. /*    x . y = 8;*/
  1137.  
  1138.     return x;
  1139. }
  1140.  
  1141. cfree(x)
  1142. char * x;
  1143. {
  1144.     free(x);
  1145. }
  1146.  
  1147. clear_canvas()
  1148. {
  1149.     set_gmode(ERASE);
  1150.  
  1151.     SetOPen(RastPort,0);
  1152. /*    RectFill(RastPort,100,10,Window -> Width - 1,Window -> Height - 1);*/
  1153.     RectFill(RastPort,0,0,AnotherWindow -> Width - 1,AnotherWindow -> Height - 1);
  1154.  
  1155.     reset_gmode();
  1156. }
  1157.